<template>

  <!--  附近智能柜页面-->

  <div class="big2">
    <!--  顶部-->
    <div class="top1">
      <van-icon class="leftjiantou" size="20px" @click="fanhui" name="arrow-left"/>
      <p class="zi1">附近智能柜</p>
      <p class="zi2" @click="myfavorites">我的收藏</p>
    </div>

    <!--  中间搜索框-->
    <div class="middle">
      <van-icon size="1.5em" class="icon3" name="location-o"/>
      <van-search v-model="value" class="middle1" placeholder="请输入地址名"/>
      <button @click="sousuo()" class="button1">搜索</button>
    </div>

    <!--  下-->
    <div class="under" v-for="i in cabinetmachine" :key="i.id">
      <div class="under1">
        <img class="img1"
             src="https://myimagezxy1.oss-cn-beijing.aliyuncs.com/lsz/%E6%99%BA%E8%83%BD%E6%9F%9C%E5%8A%9F%E8%83%BD%E9%87%8C%E7%9A%84.svg"
             alt="网络加载超时">
      </div>
      <div class="under2">
        <p class="zi3">{{ i.machineCode }}</p>
        <van-icon v-if="i.isCollection===0" class="icon1" size="1.2em" @click="Bookmarked(i.id)" name="star-o"/>
        <van-icon v-if="i.isCollection===1" class="icon2" size="1.2em" @click="Unfavorites(i.id)" name="star"/>
      </div>
      <div class="under3" @click="SmartLockerDetails(i.id)">
        <p class="zi4">{{ i.location }}{{ i.address }}</p>
      </div>
      <div class="under4">
        <p class="zi5">可用箱格:</p>
        <img class="img3" src="https://myimagezxy1.oss-cn-beijing.aliyuncs.com/lsz/%E7%AE%B1%E6%A0%BC.svg"
             alt="网络加载超时">
        <p class="zi6">{{ i.id }}/24个</p>
      </div>
  </div>

  </div>
</template>

<script>
import {findcabinetmachine, Unfavorites, Bookmarked, getaddress} from "@/api/cabinetmachine/CabinetMachine";


export default {
  data() {
    return {
      cabinetmachine: [],
      filteredCabinetMachine: [],
      form: {
        location: '',
      },
      form1: {
        location: '',
      },
      value: '',
      currentLocation: {latitude: 116.20142740946129, longitude: 40.134741440946115},
    };
  },
  created() {
    this.findCabinetMachine()
  },
  mounted() {

  },
  methods: {
    /*  查询柜机 */
    /**
     * 异步查找柜机数据
     * 此方法调用一个假设的 fetchCabinets 函数来获取柜机数据
     * 然后调用另一个方法来按距离过滤这些数据
     */
    async findCabinetMachine() {
      try {
        // 使用 findcabinetmachine 函数获取柜机数据，该函数返回一个 Promise
        findcabinetmachine(this.form).then(res => {
          this.cabinetmachine = res.data.data;
          // console.log("柜机数据:", this.cabinetmachine)
          // 数据成功获取后，打印成功获取的柜机数据
          console.log('Cabinets fetched successfully:', this.cabinetmachine);
          // 在获取数据后，调用按距离过滤柜机数据的方法
          this.filterCabinetMachineByDistance();
        })
      } catch (error) {
        // 如果在获取柜机数据过程中发生错误，打印错误信息
        console.error('Error fetching cabinets:', error);
      }
    },




    /* 根据距离过滤柜机数据 */
    /**
     * 异步过滤机柜设备，根据距离进行筛选
     * 该方法通过调用地理位置服务，获取每个机柜设备的经纬度，并计算其与当前位置的距离
     * 最后筛选出距离当前位置不超过200公里的设备
     */

    async filterCabinetMachineByDistance() {
      try {
        const MAX_RETRIES = 3; // 设置最大重试次数
        const CONCURRENCY_LIMIT = 5; // 并发请求的最大数量

        // 用于存储最终处理成功的设备列表
        const successfulItems = [];

        // 用于存储需要重试的设备列表
        const retryQueue = [...this.cabinetmachine];

        // 处理单个设备的函数
        const processItem = async (item) => {
          let retries = 0;

          while (retries < MAX_RETRIES) {
            try {
              // 调用地址获取服务，传入设备的位置信息
              const addressResponse = await getaddress({ location: item.location });
              const addressData = addressResponse.data.data;
              console.log("转换的经纬度", addressData);

              // 数据格式检查，确保返回的数据有效
              if (!addressData) {
                console.warn('Invalid data format from getaddress response:', addressResponse);
                throw new Error('Invalid data format');
              }

              // 解析经纬度数据
              const values = Object.values(addressData);
              console.log("值", values);
              const latitude = parseFloat(values[0]);
              const longitude = parseFloat(values[1]);
              console.log("纬度", latitude);
              console.log("经度", longitude);

              // 检查经纬度是否为有效数值
              if (isNaN(latitude) || isNaN(longitude)) {
                console.warn(`Invalid latitude or longitude for item: ${JSON.stringify(item)}`);
                throw new Error('Invalid latitude or longitude');
              }

              // 计算设备与当前位置的距离，并将距离信息附加到设备对象上
              item.distance = this.calculateDistance(latitude, longitude, this.currentLocation.latitude, this.currentLocation.longitude);
              console.log('Item with distance:', item); // 输出每个计算后的 item
              return item;
            } catch (error) {
              console.error('Error processing item:', error);
              retries++;
              if (retries >= MAX_RETRIES) {
                console.error(`Failed to process item after ${MAX_RETRIES} retries: ${JSON.stringify(item)}`);
                return null;
              }
              // 可选：在这里加入延迟重试，防止请求过于频繁
              // await new Promise(resolve => setTimeout(resolve, 1000));
            }
          }
        };

        // 异步并发处理设备
        const processItemsConcurrently = async () => {
          const batchPromises = retryQueue.splice(0, CONCURRENCY_LIMIT).map(processItem);
          const batchResults = await Promise.allSettled(batchPromises);

          batchResults.forEach((result) => {
            if (result.status === 'fulfilled' && result.value !== null) {
              successfulItems.push(result.value);
            }
          });

          if (retryQueue.length > 0) {
            await processItemsConcurrently();
          }
        };

        await processItemsConcurrently();

        // 过滤出距离不超过200公里的设备
        const filteredItems = successfulItems.filter(item => item.distance <= 200);

        this.cabinetmachine = filteredItems;
        console.log('Filtered items:', this.cabinetmachine); // 输出过滤后的结果
      } catch (error) {
        console.error('Error filtering cabinet machine by distance:', error);
      }
    },


    // async filterCabinetMachineByDistance() {
    //   try {
    //     // 利用 map 创建一个 Promise 数组，用于并行处理每个机柜设备的地理位置数据
    //     const promises = this.cabinetmachine.map(async item => {
    //       try {
    //         // 调用地址获取服务，传入设备的位置信息
    //         const addressResponse = await getaddress({location: item.location});
    //
    //         const addressData = addressResponse.data.data;
    //         console.log("转换的经纬度", addressData)
    //
    //         // 数据格式检查，确保返回的数据有效
    //         if (!addressData) {
    //           console.warn('Invalid data format from getaddress response:', addressResponse);
    //           return null;
    //         }
    //         // 解析经纬度数据
    //         var values = Object.values(addressData);
    //         console.log("值", values)
    //         const latitude = parseFloat(values[0]);
    //         const longitude = parseFloat(values[1]);
    //         console.log("纬度", latitude)
    //         console.log("经度", longitude)
    //
    //         // 检查经纬度是否为有效数值
    //         if (isNaN(latitude) || isNaN(longitude)) {
    //           console.warn(`Invalid latitude or longitude for item: ${JSON.stringify(item)}`);
    //           return null;
    //         }
    //
    //         // 计算设备与当前位置的距离，并将距离信息附加到设备对象上
    //         item.distance = this.calculateDistance(latitude, longitude, this.currentLocation.latitude, this.currentLocation.longitude);
    //         console.log('Item with distance:', item); // 输出每个计算后的 item
    //         return item;
    //       } catch (error) {
    //         console.error('Error processing item:', error);
    //         return null;
    //       }
    //     });
    //
    //     // 等待所有 Promise 结束，即使有错误也能继续处理
    //     const results = await Promise.allSettled(promises);
    //     console.log("111", results)
    //     // 筛选出成功处理的设备，并过滤出距离不超过200公里的设备
    //     const filteredItems = results
    //         .filter(result => result.status === 'fulfilled')
    //         .map(result => result.value)
    //         .filter(item => item !== null && item.distance <= 200);
    //     this.cabinetmachine = filteredItems;
    //     console.log('Filtered items:', this.cabinetmachine); // 输出过滤后的结果
    //   } catch (error) {
    //     console.error('Error filtering cabinet machine by distance:', error);
    //   }
    // },


    /* 计算距离 */
    calculateDistance(lat1, lon1, lat2, lon2) {
      // 假设这是一个简单的距离计算方法
      const R = 6371; // 地球平均半径，单位为公里
      const dLat = this.toRadians(lat2 - lat1);
      const dLon = this.toRadians(lon2 - lon1);
      const a =
          Math.sin(dLat / 2) * Math.sin(dLat / 2) +
          Math.cos(this.toRadians(lat1)) * Math.cos(this.toRadians(lat2)) *
          Math.sin(dLon / 2) * Math.sin(dLon / 2);
      const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
      const distance = R * c; // 距离，单位为公里
      return distance;
    },
    toRadians(degrees) {
      return degrees * (Math.PI / 180);
    },

    /* 搜索  */
    sousuo() {
      this.form1.location = this.value;
      console.log("当前信息", this.form1)
      // 验证输入是否只包含中文字符
      if (!/^[一-龥]+$/u.test(this.form1.location)) {
        this.$toast('请输入有效的中文字符');
        return;
      }
      findcabinetmachine(this.form1).then(res => {
        this.cabinetmachine = res.data.data;
        if (res == null|| res.data.data.length == 0) {
          this.$toast('附近暂无智能柜');
        }
      })
    },
    /*  跳转到智能柜详情 */
    SmartLockerDetails(id) {
      this.$router.push({path: '/smartlockerdetails/SmartLockerDetails', query: {id: id}})
    },
    /*  未收藏  */
    Unfavorites(id) {
      Unfavorites(id).then(res => {
        if (res.data.code == 200) {
          this.$toast('取消收藏成功');
          this.findCabinetMachine()
        } else {
          this.$toast('网络繁忙，稍后再试');
        }
      })
    },

    /*  已收藏  */
    Bookmarked(id) {
      Bookmarked(id).then(res => {
        if (res.data.code == 200) {
          this.$toast('收藏成功');
          this.findCabinetMachine()
        } else {
          this.$toast('网络繁忙，稍后再试');
        }
      })
    },
    /* 我的收藏 */
    myfavorites() {
      this.$router.push({path: '/myfavoritessmartcabinets/MyFavoritesSmartCabinets'})
    },

    /* 顶部左箭头返回首页 */
    fanhui() {
      this.$router.push({path: '/home/Home'})
    },
  }
}
</script>

<style scoped>

/* 大盒子总体样式 */
.big {
  width: 100%;
  height: 100%;
  background-color: #f5f5f5;
}

/* 顶部盒子  */
.top1 {
  width: 100%;
  height: 40px;
//border: 1px solid red; background-color: white;

}

.zi1 {
//border: 1px solid red; margin-top: 5px; width: 100px; height: 30px; margin-left: 35%; font-size: 17px;
}

.zi2 {
  width: 100px;
  height: 30px;
  float: right;
//border: 1px solid red; margin-top: -48px;
}

/* 顶部左边箭头 */
.leftjiantou {
  float: left;
  margin-top: 3px;
  margin-left: 10px;
}

.middle {
  width: 95%;
  margin-left: 10px;
  height: 45px;
  border: 1px solid white;
  margin-top: 39px;
  background-color: white;
}

.masklayer {
  width: 20px;
  height: 20px;
  position: fixed;
  top: 61px;
  left: 15px;
  background-color: #fdd144;
  align-content: center;
  font-size: 15px;
}

.icon3 {
//border: 1px solid red; float: left; margin: 9px 2px;
}

.middle1 {
  width: 85%;
  height: 10px;
  background-color: white;
  margin: 12px 30px;
}

.button1 {
//border: 1px solid red; float: right;
  margin-top: -36px;
  background-color: white;
  border: none;
  margin-right: -4px;
}

.under {
  width: 90%;
  height: 170px;
  background-color: white;
//border: 1px solid red; margin-left: 22px; margin-top: 10px;
}

.img1 {
  width: 22px;
  height: 30px;
}

.under1 {
  width: 40px;
  height: 80px;
//border: 1px solid red; float: left; margin-top: 5px;
}

.under2 {
  width: 80%;
  height: 30px;
//border: 1px solid red; margin-left: 50px; margin-bottom: 10px;
}

.zi3 {
//border: 1px solid red; margin-top: 10px; width: 220px; margin-left: 10px; height: 20px; text-align: left;
}

.icon1 {
  float: right;
  margin-top: -20px;
}

.icon2 {
  float: right;
  margin-top: -20px;
}

.under3 {
  width: 80%;
  height: 50px;
  border-bottom: 1px solid #f5f5f5;
//border: 1px solid red; margin-left: 50px; margin-top: 10px;
}

.zi4 {
  font-size: 15px;
  margin-left: 10px;
  text-align: left;
}

.under4 {
  width: 80%;
  height: 30px;
  margin-left: 50px;
  margin-top: 10px;
}

.zi5 {
  width: 70px;
  height: 20px;
//border: 1px solid red; float: left; margin-left: 12px;
}

.img3 {
  width: 20px;
  height: 20px;
  float: left;
  margin-left: 10px;
  margin-top: 5px;
}

.zi6 {
  width: 70px;
  height: 20px;
//border: 1px solid red; float: left;
}
</style>

